feat(plat): add support for BeagleBone AI-64#320
feat(plat): add support for BeagleBone AI-64#320puranikvinit wants to merge 12 commits intobao-project:mainfrom
Conversation
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
f3cb05b to
1b098e3
Compare
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
9cac460 to
9285933
Compare
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
|
@puranikvinit this is looking amazing! Let us know when it is at a point we can test it here. Also, if you could in parallel start a PR for bao-demos, so you could follow it step-by-step. |
feat(drivers/mailbox): add helper function to get threads by host_id and host_function fix(drivers/mailbox): code lint fixes Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
|
Hey @josecm, For |
|
Looking forward! |
|
Hey @josecm, |
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
3a54723 to
6ae3001
Compare
Do you have a board you can test with? Otherwise, I am happy to do it in the next few weeks.
But what do you mean interrupt management code? For the arm architecture all interrupt management is already there. No special need to handle platform-specifics. Or do you mean the interrupt handlers for the interrupts related to the firmware drivers you have implemented. Also I am trying to understand how those drivers will be used throughout execution. Or are they required only during initialization? Another point is that IIRC that platform has an SMMUv3, correct? We have a PR to support it for quite a while but since no platform required we didn't push it through. Should we start working on it again to support this platform? |
No, I don't have one... I will also work on the bao-demos PR this weekend, so that it helps us in testing the board as well!
So for these Jacinto SoCs, TI has a different way of managing interrupts. Instead of routing the peripheral interrupt lines directly through the GIC to the compute clusters, they have something called interrupt aggregators and interrupt routers, for extreme configurability of interrupt management. The peripheral interrupt lines all come into an interrupt aggregator. Then, each subsystem in the SoC has its own interrupt router. This is basically a m:n mux, between the interrupt aggregator and the compute cluster interrupt controller (GIC, VIM, etc...). So both these need to be configured to successfully route an interrupt line from a peripheral to a core. Here, the core cannot configure these on its own. It needs to send a message to the DMSC, requesting for this configuration, and the DMSC does the job. I have explained it in more detail in the discussion thread #311.
As of now, I see them getting utilized only for platform initialization. Specifically for interrupt configurations and other required firewall management. These drivers are only required for system management, interacting with devices outside the A722 compute cluster. Since we are dealing with a static hypervisor, I don't see it getting used otherwise.
Yes, it needs SMMUv3... We need to work on that as well. I guess we will also need firewall management APIs within TISCI drivers, if required. |
Signed-off-by: puranikvinit <kvp933.vinit@gmail.com>
I have a board available on my side. I'll try to find sometime to test once this is done.
TBH, I would assume that TF-A would configure interrupts such they are already forwarded to the A72 cluster and have fixed interrupt ID's which would be the ones found in Linux's device tree. If this is indeed required, I'd suggest setting up the interrupt routing you describe to defaults as defined by the Linux device tree.
Then yes, as you suggest, some specific platform configuration field where a user could override those routings somehow would be required. To look something like this:
Yes, this makes perfect sense. Looking forward to "required firewall management", we really want to incorporate support for firewall protection in Bao.
Nice!! Finally we can also merge the SMMUv3 support. But first I'd focus getting evertyhing else running. After we get the base functionality done, we can go for SMMU. |
|
Well, after you brought up the point of TF-A setting things up, I went into more details of the boot flow... What I saw is:
Taking all these points into consideration, we won't have to do anything wrt interrupts at all for the hosts other than what is already implemented. The only usecases where Bao needs this driver, is to register for interrupts which Bao will rely on, for example, SMMU interrupts. I should have studied implementations in more detail, before jumping in to code the drivers... What do we do? The docs still don't seem to explicitly mention these intricacies, hence the confusion. If Bao relies on SMMU interrupts, then yeah, we can have it registered in boot time, else we can strip out these drivers completely... Good learning though! |
I wouldn't say it's wasted work. As you said, it seems we will require it for initializing the SMMU interrupt. And I am guessing we will actually require these drivers even if we do not include them now.
Does u-boot setup the interrupt routing at this stage? If so (and this is the bulk of the board config you mention) we can even do this in bao directly so we don't have depend on u-boot. But not as a priority btw. If we do this, I'd leave it to after all other stuff is done.
This is another point where we might need these drivers. If guest do assume they can commicate with the DMSC, Bao needs to intercept those calls, filter them, and forward them to the DMSC. So these drivers will be useful for this functionality also. |
Okay, as far as I have understood the boot flow, we compile two distinct u-boot images, I initially thought we could use this API to dynamically reassign resources because the TI documentation uses the word 'update'. However, reading closely, they explicitly state that the actual configuration payload is 'copied and validated ONLY when the first board configuration message is received.' Therefore, 'updating' simply means turning on a new Device Group using the static rules Also, interrupt routing is done by whoever uses the interrupts. For example, when we run Linux as a guest, Linux will send requests for interrupt routing with the host ID it will see from the device tree. It is dynamic in nature, meaning whenever linux requires an interrupt to be registered, the Linux TISCI driver picks the appropriate interrupt parent from the device tree, setup a TISCI message, and directly communicate with the DMSC for the interrupt. Bao does not have to perform this routing.
Again, will Bao actually need to filter out these messages? Assuming that the SMMU, stage-2 page tables and the initial board configs by |
Thanks for explaining this in depth! Now I can reformulate my point: what I meant was just regarding the
Understood, this is very interesting and can open-up future work on how we setup these locked rules according to some Bao config. Again, only brainstorming at this point.
The first point here is exactly why I believe we need to do this. To your points:
So, if indeed Linux requires communication with DMSC to setup interrupts, Bao needs to intercept these messages and make sure Linux does not reconfigure interrupts assigned to the hypervisor or other VMs. I don't think it will cause significant increase in latency since I expect these configurations to be done only one time during Linux's boot and are not in the critical path of interupt handling. Regarding TCB bloat, I also don't see much increase to add this logic compared to the drivers you already developed. Nevertheless, we can implement this and if indeed it adds significant size to the TCB we can understand ways on how to optimize it. |
|
Sorry for the late reply!
Yes, what I meant in that comment was that it would add an additional layer of isolation for the IO devices, not that it would impact the message pipeline with the DMSC.
Well, DMSC can indeed differentiate between the hypervisor and the guest, using the corresponding host IDs. Each A72 core is assigned 3 secure proxy channels (1 secure, 2 non-secure), each of which are hw isolated. The secure proxy address space itself is isolated, hence the offset calculations performed in the driver. The EL3 application gets 1 host ID (secure), the EL2 application (Bao in this case) gets 1 (non-secure) and the EL1/EL0 application (the guest in this case) gets the remaining one. In short, the DMSC can clearly distinguish between Bao and the guests. The trap and emulate approach which you talked about would be absolutely necessary, if this difference didn't exist, but with that in place now, I don't see a need to have an approach like that.
Precisely my concern. As a platform developer, this becomes unmaintainable. I cannot cater to the specific needs of every guest application that would ever boot as a guest from Bao. The easiest way out here, and a fairly practical one, is to let the users take care of the board configs, before they compile u-boot. It is feasible as well, because of the static nature of the hypervisor. The user would know the mappings beforehand, we just inform them to configure it. The trap and emulate approach would make sense for a dynamic hypervisor where vCPU > pCPU, but the static nature makes it easier for us! |
Signed-off-by: Vinit Puranik <kvp933.vinit@gmail.com>
|
Hey @josecm, Just checking in to see if you've had a chance to look at the comment I left above... Please let me know if there are any more details you expect from me, or some things I need to rethink and reconsider about! |
|
Hey @puranikvinit, sorry for the delay. We have been at embedded world this past week.
This is good news. My question now is how do we tell the DMSC which resources can the guest act upon? Furthermore, does it distinguish the request's source core, so we can differentiate not only between guest/hypervisor but also between the different guests running on different cores?
This seems the more direct approach, yes. Even if we decide for this, we can do it post the first patch for the platform support. Can you point me somewhere that describes how this configuration is done? Does TI provide any specific tool for this?
Nevertheless, we should keep this case in mind. We've been experimenting with CPU overcommitment support. |
|
Ohh yeah, the Embedded World thing completely slipped out of my mind, apologies! I would love to hear more about the trends and interactions you saw there when you have a moment!
That is configured in the Resource Manager (RM) Board Configuration API that is issued at the start of the boot flow, like we discussed the other day! This is exactly what we ask the user to configure in
Yes. That split of 6 host IDs which I mentioned in the earlier comment, is on a per-core basis. So, indeed the DMSC can differentiate between the guests running on different cores
Yes, TI does provide a tool for this: It is called the K3 Resource Partitioning Tool. This tool basically allows us to configure this data structure that will be passes to the DMSC in the early stages of the boot flow with a GUI, and generates a
Ohhh I wasn't aware of this, I will definitely take a look at this, and its implications on this platform support patch. Thanks for the heads-up! If you don't mind, I would also like to understand what led to Bao experimenting with overcommitment support, and how things are taking shape there... |
I will take a look at the tool to understand if it fits does our needs. If so, for now we can follow the approach you mention: (i) use the partitioning tool to setup resources and assign them to the hypervisor and each guest, (ii) setup bao's config matching the tool's setup, (iii) pass the tool output to u-boot. Nevertheless, in the future, ideally bao wouldn't depend on this tool and would do the configuration u-boot is doing based solely on the configuration file.
Basically many people have come to us interested and Bao but see fully static partitioning as a limitation. Our goal is to add support for cpu sharing but do so in a way that if the hypervisor is configured purely in a static partitioning setup, you don't lose any of the original guarantees with respect to isolation and real-time. |
|
@puranikvinit I've setup the tool, but I am finding it hard to understand what to configure wrt interupt routing: Can you guide me on this or point to some detailed documentation? |
|
That tool, is for configuring the resource firewall for the cores... The interrupt routing is to be done with a different message, and that can be done from within Bao itself! The routing request API will go through, if the resources involved in the routing are available for the host in question, which is what we configure in the system partitioning tool... |
Oh OK. But I am a bit confused now. Two points:
|
In short, what happens here is, Interrupt Aggregators allow us to create virtual interrupts, where we can play with combining interrupts into 1 line, and stuff like that. Interrupt Routers, are basically n:m muxes, that allow the compute cluster interrupt controller to subscribe to the virtual interrupts that we configure in the aggregator. This is the page where the resource IDs for each resource is documented.
This is the understanding I have gained from the TRM and looking at the allocation configs. I might be wrong at some places, but I believe I got the gist of it right,,, |
|
The references you point make it very clear for me what the interrupt aggregation/routing is now. As for the two points we were discussing:
I say we go for the default config as I believe Linux is using.
"We will allow them to do it directly, but also ask the user to make sure that they are passing in the correct host ID in the device tree" This worries me a lot. From a security perspective, even if we tell the guest to use a given host ID, it could theoretically use a different one and mess up other VMs' interrupts? We can't allow this. |
|
@puranikvinit Neverthless, I'd say you push through with the port without minding this. Once we get guests booting we can go back and decide what to do regarding these issues. |
That shouldn't be an issue. The secure proxy channels have physical isolation. Every host can write to only one channel mailbox, to which it will have access. Even in case it tries to proxy with a different host ID, the DMSC will check the host ID in the request payload with the channel it received the message in, and if it doesn't match, it will have a panic sequence as well... Not sure about that sequence though!
Sure, for now, other than the SMMU interrupt routing request, the platform code is mostly in place, I guess we can try booting up Bao for now, and debug further... I have written the code to the best of my knowledge, but there may be many "gotchas" in there which we will figure out eventually, as this is my first time with TDA SoCs... |
Oh now everything fits perfectly! Let's leave handling the panic as a TODO for now. But how is the panic reported? Could it be forwarded as an interrupt to the hypervisor?
Is it everthing in place? If so we should start testing it, yes! Would it be possible for you do add the board to bao-project/bao-baremetal-guest too? So we can start with an easy guest where we have full control to validate bao, then go for Linux. |
I am not sure about the interrupts here, but the message sent by the Host is received back by the host as a NACK. A valid message is responded back with an ACK, if the appropriate flag is set in the request payload... I need to look into the TRM again, to see if there are any interrupts raised as part of the panic sequence...
Sure, I will get started with the baremetal guest in the meanwhile, to set things up! |



This PR introduces support for the BeagleBone AI-64 platform, featuring TI's TDA4VM SoC with the K3 (keystone3) architecture.